package ntu.metaweb.storage;

import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Vector;

import rice.p2p.commonapi.Id;
import rice.p2p.commonapi.rawserialization.OutputBuffer;

import ntu.metaweb.XMLMarshaller;
import ntu.p2p.dht.DHTContent;
import ntu.p2p.dht.DHTContentKey;
import ntu.p2p.dht.DHTContents;
import ntu.p2p.past.OverwritableContentHashPastContent;

public class WebPage implements DHTContent {

	private static final long serialVersionUID = -3087316124883078965L;
	private static int nextCommentId = 0;
	
	private WebPageKey key;
	private URL url;
	private Date timestamp;
	private HashMap<Integer, Comment> comments;
	private Vector<Comment> firstLevelComments;
	private HashMap<Integer,Integer> childToParentIndex;
	
	public WebPage(WebPageKey key, URL url) {
		URI temp;
		try {
			temp = url.toURI();
			temp = new URI(temp.getScheme(), temp.getUserInfo(), temp.getHost(), temp.getPort(), 
					temp.getPath(), null, temp.getFragment());
			this.url = temp.toURL();
		} catch (URISyntaxException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (MalformedURLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		this.key = key;
		this.timestamp = Calendar.getInstance().getTime();
		this.comments = new HashMap<Integer, Comment>();
		this.firstLevelComments = new Vector<Comment>();
		this.childToParentIndex = new HashMap<Integer, Integer>();
	}
	
	public void addComment(Comment newComment) {
		newComment.setId(nextCommentId++);
		this.comments.put(newComment.getId(), newComment);
		if (newComment.getParentId() != -1) {
			this.childToParentIndex.put(newComment.getId(), newComment.getParentId());
		} else {
			this.firstLevelComments.add(newComment);
		}
	}
	
	public URL getURL() {
		return this.url;
	}
	
	public Date getTimestamp() {
		return this.timestamp;
	}
	
	public Iterator<Comment> getFirstLevelComments() {
		return this.firstLevelComments.iterator();
	}
	
	public Iterator<Comment> getComments() {
		return this.comments.values().iterator();
	}
	
	public int getCommentsNumber() {
		return this.comments.values().size();
	}
	
	@Override
	public int hashCode() {
		return this.url.hashCode();
	}
	
	@Override
	public boolean equals(Object o) {
		if (!(o instanceof WebPage)) {
			return false;
		}
		WebPage webPage = (WebPage) o;
		return this.url.equals(webPage.url);
	}

	@Override
	public DHTContentKey getKey() {
		return this.key;
	}

	@Override
	public void serialize(OutputBuffer buf) throws IOException {
		String temp = XMLMarshaller.getInstance().marshall(this);
		buf.writeInt(temp.length());
		buf.write(temp.getBytes(), 0, temp.length());
	}
}
